package com.demo.weather.receiver;

import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * 实时监测组
 * 
 * @author tangheng
 */
@Slf4j
@Getter
public class RealTimeMonitorGroup {
	
	private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yy年MM月dd日HH:mm:ss");
	
	/**数据时间*/
	private LocalDateTime date = null;
	
	private RealTimeMonitorN[] realTimeMonitors = {
			new RealTimeMonitorN(1, "水质浊度", false, 0.1D, "NTU"),
			new RealTimeMonitorN(2, "水质溶解氧", true, 0.01D, "mg/L"),
			new RealTimeMonitorN(3, "水质电导率", true, 0.01D, "ms/cm"),
			new RealTimeMonitorN(4, "水质pH值", true, 0.01D, ""),
			new RealTimeMonitorN(5, "水质盐分", true, 0.01D, "g/L"),
			new RealTimeMonitorN(6, "环温", false, 0.1D, "℃"),
			new RealTimeMonitorN(7, "环湿", true, 0.1D, "%RH"),
			new RealTimeMonitorN(8, "露点", false, 0.01D, "℃"),
			new RealTimeMonitorN(9, "风向", true, 1D, "°"),
			new RealTimeMonitorN(10, "风速", true, 0.1D, "m/s"),
			new RealTimeMonitorN(11, "2分钟平均风速", true, 0.1D, "m/s"),
			new RealTimeMonitorN(12, "10分钟平均风速", true, 0.1D, "m/s"),
			new RealTimeMonitorN(13, "雨量间隔累计", true, 0.1D, "mm"),
			new RealTimeMonitorN(14, "雨量日累计", true, 0.1D, "mm"),
			new RealTimeMonitorN(15, "PM10", true, 1D, "μg/m³"),
			new RealTimeMonitorN(16, "臭氧", true, 0.01D, "ppm"),
			new RealTimeMonitorN(17, "土壤温度1", false, 0.1D, "℃"),
			new RealTimeMonitorN(18, "土壤温度2", false, 0.1D, "℃"),
			new RealTimeMonitorN(19, "土壤温度3", false, 0.1D, "℃"),
			new RealTimeMonitorN(20, "土壤温度4", false, 0.1D, "℃"),
			new RealTimeMonitorN(21, "土壤温度5", false, 0.1D, "℃"),
			new RealTimeMonitorN(22, "土壤温度6", false, 0.1D, "℃"),
			new RealTimeMonitorN(23, "土壤温度7", false, 0.1D, "℃"),
			new RealTimeMonitorN(24, "土壤温度8", false, 0.1D, "℃"),
			new RealTimeMonitorN(25, "土壤温度9", false, 0.1D, "℃"),
			new RealTimeMonitorN(26, "土壤温度10", false, 0.1D, "℃"),
			new RealTimeMonitorN(27, "土壤湿度1", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(28, "土壤湿度2", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(29, "土壤湿度3", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(30, "土壤湿度4", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(31, "土壤湿度5", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(32, "土壤湿度6", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(33, "土壤湿度7", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(34, "土壤湿度8", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(35, "土壤湿度9", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(36, "土壤湿度10", true, 0.1D, "%m³/m³"),
			new RealTimeMonitorN(37, "土壤电导率", true, 0.01D, "ms/cm"),
			new RealTimeMonitorN(38, "土壤pH值", true, 0.01D, ""),
			new RealTimeMonitorN(39, "土壤盐分", true, 0.01D, "g/L"),
			new RealTimeMonitorN(40, "电量", true, 0.1D, "V"),
			new RealTimeMonitorN(41, "气压", true, 0.1D, "hPa"),
	};
	
	private RealTimeMonitorGroup() {}
	
	public static RealTimeMonitorGroup of(byte[] bytes) {
		if(bytes.length % 2 != 0) {
			throw new IllegalArgumentException(String.format("数值参数一定是2的倍数: %d", bytes.length));
		}
		
		log.debug("通道数据长度: {}", bytes.length);
		
		RealTimeMonitorGroup group = new RealTimeMonitorGroup();

		// 时间，6个字节
		group.date = LocalDateTime.of(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]);
//		LocalDateTime date = LocalDateTime.now();
//		date.withYear(bytes[0])
//			.withMonth(bytes[1])
//			.withDayOfMonth(bytes[2])
//			.withHour(bytes[3])
//			.withMinute(bytes[4])
//			.withSecond(bytes[5]);
//		group.date = date;
		log.debug("通道数据时间: {}", group.date.format(dateFormat));
		
		// 通道监测数据
		byte[] dataBytes = Arrays.copyOfRange(bytes, 6, bytes.length);
		for(int i=0; i<dataBytes.length; i+=2) {
			int pos = i/2;
			if(pos > group.realTimeMonitors.length) {
				// TODO 处理超范围情况
				continue;
			}

			RealTimeMonitorN monitor = group.realTimeMonitors[pos];
			monitor.setValue(getValueWithUnsign(monitor.isUnsiged(), new byte[] {dataBytes[i], dataBytes[i+1]}));
		}
		log.debug("实时监测数据: {}", group);
		return group;
	}
	
	private static int getValueWithUnsign(boolean unsign, byte[] bytes) {
		// 无符号整数
		if(unsign) {
			return ((bytes[0] & 0xff) << 8) | (bytes[1] & 0xff); 
		}
		
		// 有符号整数
		return ByteBuffer.wrap(bytes).getShort();
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		Arrays.stream(realTimeMonitors).forEach(m -> sb.append("\n").append(m.toString()));
		return sb.toString();
	}
}